﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace TankBattle.Models
{
 
    public class Tank: GameObject
    {
        #region variable

        protected int flag;
        protected int preFlag;
        protected int shootSpeed;
        protected int shoot;
        protected int timeCount;
        protected bool shooting;


        protected int speed;
        protected int bulletType;

        protected Vector2 radiusWH;
        protected Vector2 radiusXY;
        protected Sprite sprite;

        #endregion

        #region Construction 
        public Tank()
        { }
        public Tank(Texture2D texture, Vector2 position)
        {
            this.flag = Constant.ZERO;
            Intallization(texture, position,
                Constant.TANK_SIZE_WIDTH, Constant.TANK_SIZE_HEIGHT);
        }
        public Tank(Texture2D texture, Vector2 position, int width, int height, int flag)
        {
            this.flag = flag;
            Intallization(texture, position, width, height);
        }

        #endregion 

        #region Properties
        public override Rectangle Polygon
        {
            get
            {
                SetRadius();
                return new Rectangle(
                    (int)position.X ,
                    (int) position.Y,
                    (int)(width - radiusWH.X),
                    (int)(height - radiusWH.Y));
            }
        }
        public int BulletType
        {
            get
            {
                return bulletType;
            }
        }
        #endregion 

        #region Set Function
        public void SetSpeed(int speed)
        {
            if (speed != Constant.ZERO) 
            this.speed = speed;
        }
        public void SetBulletType(int bullet)
        {
            if (bullet != Constant.ZERO) 
                this.bulletType = bullet;
        }
        public void SetLife(int life)
        {
            if (life != Constant.ZERO)
                this.life += life;
        }
        public void SetShootSpeed(int shootSpeed)
        {
              this.shootSpeed += shootSpeed;
        }
        #endregion 

        #region Main Function
        //Thực hiện các bước di chuyên
        public virtual void Move(List<GameObject> obstructions)
        {
            if (stop) return;
            if (flag != Constant.ZERO)
            {
                if (TestMove(obstructions))
                {
                    SetMove();
                }
                if (flag != preFlag)
                {
                    SetState();
                    preFlag = flag;
                }
            }
        }
        public virtual bool Shoot()
        {
            if (shoot <= shootSpeed)
            {
                shoot++;
                return true;
            }
            return false;
        }
        public virtual Bullet Shoot(Texture2D texture)
        {
            shooting = true;
            int temp = flag;
             if (temp == 0) temp = preFlag;
            SetStateShoot(temp);
            return new Bullet(texture, GetBulletPosition(temp), temp ,bulletType);
        }
        protected override void Intallization(Texture2D texture, Vector2 position, int width, int height)
        {
            base.Intallization(texture, position, width, height);

            sprite = new Sprite(texture,
                new Vector2(width, height),
                new Vector2(Constant.TANK_SHEET_X, Constant.TANK_SHEET_Y),
                Constant.RATE_TANK, false);

            radiusWH = new Vector2(0, 0);
            radiusXY = new Vector2(0, 0);

            #region Giản cách của viên đạn được bắn
            shoot = Constant.ZERO;
            shooting = false;
            timeCount = 0;
            #endregion 

            #region Thuộc tính của xe
            preFlag = flag;
            speed = Constant.TANK_SPEED_NORMAL;
            bulletType = Constant.BULLET_TYPE_NORMAL;
            shootSpeed = Constant.ZERO;
            undead = false;
            #endregion 
        }
        public override bool Update()
        {
            if (flag != 0 || shooting)
            {
                if (sprite.Update())
                {
                    SetState();
                    shooting = false;
                }
            }
            timeCount++;
            if (timeCount > Constant.TANK_SHOOT_DELAY)
            {
                timeCount = 0;
                ResetShoot();
            }
            //if (!sprite.Update()) SetState();
            return base.Update();
        }
        public override void Draw(SpriteBatch spriteBatch)
        {
            sprite.Draw(spriteBatch, position);
            base.Draw(spriteBatch);
        }
        #endregion

        #region Other Function
        //Kiểm tra có thể di chuyển hay không 
        public virtual bool TestMove(List<GameObject> Obstructions)
        {
            //Giả định di chuyển 
            Vector2 tempPosition = new Vector2(position.X, position.Y);
            switch (flag)
            {
                case (Constant.MOVE_LEFT):
                    tempPosition.X -= speed;
                    break;
                case (Constant.MOVE_RIGHT):
                    tempPosition.X += speed;
                    break;
                case (Constant.MOVE_UP):
                    tempPosition.Y -= speed;
                    break;
                case (Constant.MOVE_DOWN):
                    tempPosition.Y += speed;
                    break;
                default: return false;
            }
            if (!TestPosition(Obstructions, tempPosition)) return false;
            
            //Thiết lập di chuyển thành công 

            return true;
        }
        //Kiểm tra tọa độ khả thi 
        protected virtual bool TestPosition(List<GameObject> Obstructions, Vector2 tempPosition)
        {
           SetRadius ();
            if (testCrashLimit(tempPosition)) return false;
            if (Obstructions != null)
                foreach (GameObject obj in Obstructions)
                {
                    if (obj != null && !obj.Hidden)
                    { 
                        if (obj.Polygon.Intersects( new Rectangle(
                            (int) (tempPosition.X + radiusXY.X),
                            (int) (tempPosition.Y + radiusXY.Y),
                            (int) (width - radiusWH.X),
                            (int) (height - radiusWH.Y))))
                        {
                            return false;
                        }
                    }
                }
            return true;
        }
        //Trạng thái hình ảnh
        protected virtual void SetState()
        {
            int temp = flag;
            if (temp == 0) temp = preFlag;
            switch (temp)
            {
                case (Constant.MOVE_UP):
                    sprite.SetCurrentFrame(new Vector2(0, Constant.FRAME_UP));
                    break;
                case (Constant.MOVE_DOWN):
                    sprite.SetCurrentFrame(new Vector2(0, Constant.FRAME_DOWN));
                    break;
                case (Constant.MOVE_LEFT):
                    sprite.SetCurrentFrame(new Vector2(0, Constant.FRAME_LEFT));
                    break;
                case (Constant.MOVE_RIGHT):
                    sprite.SetCurrentFrame(new Vector2(0, Constant.FRAME_RIGHT));
                    break;
            }
        }   
        //Trạng thái hình khi bắn
        protected virtual void SetStateShoot(int flag)
        {
            switch (flag)
            {
                case (Constant.MOVE_LEFT):
                    sprite.SetCurrentFrame(new Vector2(0, Constant.FRAME_SHOOT_LR));
                    break;
                case (Constant.MOVE_RIGHT):
                    sprite.SetCurrentFrame(new Vector2(0, Constant.FRAME_SHOOT_RL));
                    break;
                case (Constant.MOVE_UP):
                    sprite.SetCurrentFrame(new Vector2(0, Constant.FRAME_SHOOT_UP));
                    break;
                case (Constant.MOVE_DOWN):
                    sprite.SetCurrentFrame(new Vector2(0, Constant.FRAME_SHOOT_DOWN));
                    break;
            }
        }
        //Thiết lập radius
        protected virtual void SetRadius()
        {
            switch (flag)
            {
                case (Constant.MOVE_DOWN):
                    radiusXY.X = 0;
                    radiusXY.Y = 10;
                    radiusWH.X = 15;
                    radiusWH.Y = 10;
                    break;
                case (Constant.MOVE_LEFT):
                    radiusWH.Y = 15;
                    radiusWH.X = 20;
                    radiusXY.X = 0;
                    radiusXY.Y = 0;
                    break;
                case (Constant.MOVE_UP):
                    radiusWH.Y = 20;
                    radiusWH.X = 15;
                    radiusXY.X = 0;
                    radiusXY.Y = 0;
                    break;
                case (Constant.MOVE_RIGHT):
                    radiusXY.X = 10;
                    radiusXY.Y = 0;
                    radiusWH.Y = 15;
                    radiusWH.X = 5;
                    break;
            }
        }
        //Các bước di chuyển
            #region MoveFunction 
        protected virtual void SetMove()
        {
            switch (flag)
            {
                case (Constant.MOVE_LEFT):
                    MoveLeft();
                    break;
                case (Constant.MOVE_RIGHT):
                    MoveRight();
                    break;
                case (Constant.MOVE_UP):
                    MoveUp();
                    break;
                case (Constant.MOVE_DOWN):
                    MoveDown();
                    break;
            }
        }
        protected virtual void MoveUp()
        {
            position.Y -= speed;
        }
        protected virtual void MoveDown()
        {
            position.Y += speed;
        }
        protected virtual void MoveLeft()
        {
            position.X -= speed;
        }
        protected virtual void MoveRight()
        {
            position.X += speed;
        }
        #endregion
        //Tọa độ viên đạn
        protected virtual Vector2 GetBulletPosition(int temp)
        {
            SetRadius();
            Vector2 position = new Vector2(this.position.X, this.position.Y);
            switch (temp)
            {
                case (Constant.MOVE_LEFT):
                    position.Y += (height - radiusWH.Y) / 2 - Constant.BULLET_WIDTH/2;
                    position.X -= (Constant.BULLET_WIDTH);
                    break;
                case (Constant.MOVE_RIGHT):
                    position.X += width - radiusWH.X ;
                    position.Y += (height - radiusWH.Y) / 2 - Constant.BULLET_WIDTH / 2;
                    break;
                case (Constant.MOVE_UP):
                    position.X += (width - radiusWH.X) / 2 - Constant.BULLET_WIDTH / 2;
                    position.Y -= Constant.BULLET_WIDTH;
                    break;
                case (Constant.MOVE_DOWN):
                    position.X += (width - radiusWH.X) / 2 - Constant.BULLET_WIDTH / 2;
                    position.Y += height - radiusWH.Y ;
                    break;
            }
            return position;
        }
        protected virtual void ResetShoot()
        {
            shoot = 0;
        }
        #endregion 

    }
}
